"""
-*- coding: utf-8 -*-
@Author  : Link
@Time    : 2022/4/29 15:27
@Software: PyCharm
@File    : ui_main.py
@Remark  : 
"""

import pandas as pd
import psutil
import datetime as dt
from typing import List, Dict, Union

from PySide2.QtCore import QTimer, Slot, Qt, QObject, QDir
from PySide2.QtGui import QIcon, QPixmap
from PySide2.QtWidgets import QMainWindow, QApplication, QWidget, QVBoxLayout, QMdiArea, QMessageBox, \
    QInputDialog, QAction, QFileSystemModel, QTreeView

from pyqtgraph.dockarea import *

from chart_core.chart_pyqtgraph.ui_components.chart_sample_line import PyqtCanvas
from common.app_variable import GlobalVariable
from ui_component.ui_common.my_text_browser import UiMessage, MQTextBrowser, Print
from ui_component.ui_common.ui_utils import MdiLoad, EmailThread
from ui_component.ui_main.mdi_data_concat import ContactWidget
from ui_component.ui_main.ui_designer.ui_main import Ui_MainWindow
from ui_component.ui_main.ui_setting import SettingWidget
from ui_component.ui_analysis_stdf.ui_stdf import StdfLoadUi
from ui_component.ui_app_variable import UiGlobalVariable
from var_language import BaseConfig, language


class Main_Ui(QMainWindow, Ui_MainWindow):
    mdi_count = 0
    mdi_cache: Dict[int, MdiLoad] = None
    focus_id = 0

    def __init__(self, parent=None):
        super(Main_Ui, self).__init__(parent)
        self.setupUi(self)
        self.icon = QIcon()
        self.icon.addPixmap(QPixmap(":/pyqt/source/images/icon_swf.svg"), QIcon.Normal, QIcon.Off)
        self.setWindowIcon(self.icon)
        self.area = DockArea()
        self.setCentralWidget(self.area)

        " 单纯用来存放MDI, MDI还是需要放入MERGE和CONTACT功能的 "
        self.mdi_cache = {}

        " 专用于对可视化的配置 "
        self.plot_setting = SettingWidget(self)
        self.dock_plot = Dock("110 Chart Setting", size=(100, 600))
        self.dock_plot.addWidget(self.plot_setting)
        self.plot_setting.comboBox.currentIndexChanged[str].connect(self.q_action_visible)

        " 在table下面放一个较小的QTextBrowser,来做一些信息的记录 "
        self.text_browser = MQTextBrowser(self)
        dock_text_browser = Dock("111 Text Browser", size=(100, 400))
        dock_text_browser.addWidget(self.text_browser)

        self.area.addDock(self.dock_plot, "left")
        self.area.addDock(dock_text_browser, "bottom", self.dock_plot)

        # " 开源版加一个文件管理的Tree, 有网络路径后太卡了, 待定 "
        # self.file_model = QFileSystemModel(self)
        # self.file_model.setNameFilters(GlobalVariable.STD_SUFFIXES)
        # self.file_model.setRootPath(BaseConfig.ROOT_PATH)
        # self.file_model.setFilter(QDir.Drives)
        # self.file_tree = QTreeView(self)
        # self.file_tree.setModel(self.file_model)
        # self.file_tree.setAnimated(False)
        # self.file_tree.setSortingEnabled(True)
        # self.file_tree.setAlternatingRowColors(True)
        # dock_file_tree = Dock("113 File Tree", size=(100, 400))
        # dock_file_tree.addWidget(self.file_tree)
        # self.area.addDock(dock_file_tree, "bottom", self.dock_plot)

        """
        新版本集成在一起
        载入和数据空间是比较考验的, 里面集成的东西过于复杂
        """
        self.load_widget_mdi = QMdiArea(self)
        self.load_widget_mdi.scrollContentsBy(2000, 2000)
        self.load_widget_mdi.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.load_widget_mdi.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        dock_stdf_windows = Dock("120 Load STDF Mdi Widget", size=(400, 300))
        self.area.addDock(dock_stdf_windows, "right")
        dock_stdf_windows.addWidget(self.load_widget_mdi)

        self.cpu_percent = []
        self.rom_percent = []
        self.monitor_widget = QWidget(self)
        self.monitor_widget_verticalLayout = QVBoxLayout(self.monitor_widget)
        self.cpu_percent_pg, _ = PyqtCanvas.set_graph_ui(self.monitor_widget_verticalLayout, "CPU占用监控")
        self.rom_percent_pg, _ = PyqtCanvas.set_graph_ui(self.monitor_widget_verticalLayout, "内存占用监控")

        dock_monitor = Dock("112 System Status", size=(100, 300))
        dock_monitor.addWidget(self.monitor_widget)

        self.area.addDock(dock_monitor, "bottom", dock_text_browser)
        self.area.moveDock(dock_text_browser, 'above', dock_monitor)

        self.mdi_contact_dialog = ContactWidget(None, self.icon)
        self.mdi_contact_dialog.messageSignal.connect(self.mdi_space_message_emit)
        self.mdi_contact_dialog.dataSignal.connect(self.mdi_space_data_contact)

        self.recode_timer = QTimer(self)
        self.recode_timer.timeout.connect(self.recode_system_status)
        self.recode_timer.start(3000)

        # self.show_message_timer = QTimer(self)
        # self.show_message_timer.timeout.connect(self.show_message)
        # self.show_message_timer.start(20000)

        QTimer.singleShot(2000, self.show_message)

        self.email_thread = EmailThread(self)
        self.q_action_visible(UiGlobalVariable.PLOT_BACKEND[0])

        if not GlobalVariable.LICENSE_CONTROL:
            for each in UiGlobalVariable.WEB_ACTIONS:
                action: QAction = getattr(self, each.name)
                action.setVisible(False)
        if BaseConfig.EN:
            self.retranslate()

    def m_append(self, mes: UiMessage):
        self.text_browser.m_append(mes)

    def show_message(self):
        self.text_browser.mes_append(
            UiMessage.Error(language.Message)
        )
        # self.text_browser.mes_append(
        #     UiMessage.Debug("欢迎一起探讨超高速, 大电压, 大电流, 数字, 模拟等相关硬件开发以及ATE调试技术, 以及良率提升分析手段")
        # )

    def recode_system_status(self):
        """
        系统状态监控
        :return:
        """
        if len(self.rom_percent) > 320:
            self.rom_percent.pop(0)
            self.cpu_percent.pop(0)
        rom_percent = psutil.virtual_memory()[2]
        cpu_percent = psutil.cpu_percent()
        self.rom_percent.append(rom_percent)
        self.cpu_percent.append(cpu_percent)
        rom_pen = '#FFA500' if rom_percent > 85 else 'g'
        cpu_pen = '#FFA500' if cpu_percent > 85 else 'g'
        rom_pen = 'r' if rom_percent > 95 else rom_pen
        cpu_pen = 'r' if cpu_percent > 95 else cpu_pen
        self.cpu_percent_pg.plot(self.cpu_percent, pen=cpu_pen, clear=True)
        self.rom_percent_pg.plot(self.rom_percent, pen=rom_pen, clear=True)

    @Slot()
    def on_action_add_stdf_module_triggered(self):
        """
        加载模块, 到MDI空间中
        :return:
        """
        self.mdi_count += 1
        home_load_mdi = StdfLoadUi(self, space_nm=self.mdi_count)
        home_load_mdi.closeSignal.connect(self.mdi_space_delete)
        self.mdi_cache[self.mdi_count] = MdiLoad(
            self.mdi_count, home_load_mdi, "STDF数据载入空间: {}".format(self.mdi_count)
        )
        self.load_widget_mdi.addSubWindow(home_load_mdi)
        home_load_mdi.show()

    @Slot()
    def on_action_path_select_triggered(self):
        """
        加载模块, 到MDI空间中, 这个是选取文件夹
        """
        self.mdi_count += 1
        home_load_mdi = StdfLoadUi(self, space_nm=self.mdi_count, path_select=True)
        home_load_mdi.closeSignal.connect(self.mdi_space_delete)
        self.mdi_cache[self.mdi_count] = MdiLoad(
            self.mdi_count, home_load_mdi, "STDF数据载入空间: {}".format(self.mdi_count)
        )
        self.load_widget_mdi.addSubWindow(home_load_mdi)
        home_load_mdi.show()

    @Slot()
    def on_action_pyside2_triggered(self):
        QApplication.aboutQt()

    @Slot()
    def on_action_email_triggered(self):
        if self.message_show(
                'mail.To = "lihuan.hello@qq.com"\r\nmail.Cc = "865789047@qq.com"\r\n点击确认使用outlook反馈问题'
        ):
            if self.email_thread.isRunning():
                return
            self.email_thread.start()

    @Slot()
    def on_action_cascade_triggered(self):
        self.load_widget_mdi.cascadeSubWindows()

    @Slot()
    def on_action_tiled_triggered(self):
        self.load_widget_mdi.tileSubWindows()

    @Slot(str)
    def q_action_visible(self, backend: str):
        for each in UiGlobalVariable.ALL_CHART_ACTIONS:
            action: QAction = getattr(self, each.name)
            action.setVisible(False)
        if backend == UiGlobalVariable.PLOT_BACKEND[0]:
            for each in UiGlobalVariable.QT_GRAPH_CHARTS:
                action: QAction = getattr(self, each.name)
                action.setVisible(True)

    @Slot()
    def on_action_contact_triggered(self):
        """
        用于数据contact, 将两份或是多份数据contact在一起来组合分析, 生成一个新的界面, 而且界面可以简单一些, 加载的功能项目少一点
        数据 contact summary 和 li
        :return:
        TODO:
            1. 要找到当前所有的mid, 在mdi_cache中
            2. mdi_cache的键是mdi_count(small int),
            3. 获取到值(MdiLoad类型)的name
            4. 最终合成一份没有tree_load的widget(hide)
        """
        if not self.mdi_cache:
            return self.mdi_space_message_emit("无法进行Contact, 无任何可Contact窗口")
        self.mdi_contact_dialog.insert(self.mdi_cache)
        self.mdi_contact_dialog.show()

    @Slot(pd.DataFrame)
    def mdi_space_data_contact(self, summary: pd.DataFrame):
        """ 根据弹出的选择界面, 用来将多个mdi的数据contact在一起 """
        self.mdi_count += 1
        merge_mdi = StdfLoadUi(self, space_nm=self.mdi_count, select=False)
        merge_mdi.dock_stdf_load.hide()
        self.mdi_cache[self.mdi_count] = MdiLoad(
            self.mdi_count, merge_mdi, "STDF数据载入空间: {}".format(self.mdi_count)
        )
        """ 设置数据 """
        merge_mdi.summary.set_data(summary)
        merge_mdi.tree_load_widget.set_tree()
        self.load_widget_mdi.addSubWindow(merge_mdi)
        merge_mdi.show()

    @Slot(str)
    def mdi_space_message_emit(self, message: str):
        """
        append message
        :param message:
        :return:
        """
        self.statusbar.showMessage("==={}==={}===".format(dt.datetime.now().strftime("%H:%M:%S"), message))

    def delete_mdi(self, count_id):
        mdi = self.mdi_cache.get(count_id, None)
        if mdi is not None:
            del mdi
            del self.mdi_cache[count_id]

    @Slot(int)
    def mdi_space_delete(self, count_id: int):
        QTimer.singleShot(100, lambda: self.delete_mdi(count_id))

    def message_show(self, text: str) -> bool:
        res = QMessageBox.question(self, '待确认', text,
                                   QMessageBox.Yes | QMessageBox.No,
                                   QMessageBox.Yes)
        if res == QMessageBox.Yes:
            return True
        else:
            return False

    def save_df_to_csv(self, data_object: pd.DataFrame, file_path):
        if data_object is None:
            return self.mdi_space_message_emit('未查询 空数据无法保存!!! ')
        if any(data_object):
            data_object.sort_values(by="PART_ID", inplace=True)
            data_object.to_csv(file_path, encoding='utf_8_sig', index=False)
            self.mdi_space_message_emit(f'数据保存成功,路径在:>>>{file_path},开始执行JMP脚本')
            return file_path
        else:
            self.mdi_space_message_emit('未查询 空数据无法保存!!! ')
            return None


class Application(QApplication):
    def __init__(self, argv):
        QApplication.__init__(self, argv)
        # QApplication.setStyle('fusion')
